﻿using AutoMapper;
using BlogSystem.Common.Config.DI.annotation;
using BlogSystem.Common.Util;
using BlogSystem.Data.Entity;
using BlogSystem.Data.Repository.RepositoryImpl;
using BlogSystem.Exception;
using BlogSystem.Model.Request;
using BlogSystem.Model.Respones;
using FluentValidation;

namespace BlogSystem.Service.Impl;

[Ioc("scoped")]
public class UserServiceImpl : IUserService
{
    //授权 协助token 的生成
    private readonly JWTHelper JwtHelper;
    
    private readonly IMapper _mapper;

    //表单数据校验
    private readonly IValidator<LoginRequets> _loginValidator;
    private readonly IValidator<RegisterRequest> _registerValidator;

    private readonly UserRepository _userRepository;

    public UserServiceImpl(UserRepository userRepository,IMapper mapper,JWTHelper jwtHelper,IValidator<LoginRequets> loginValidator,IValidator<RegisterRequest> registerValidator)
    {
        this.JwtHelper = jwtHelper;
        _loginValidator = loginValidator;
        _registerValidator = registerValidator;
        _mapper = mapper;
        _userRepository = userRepository;
    }

    
    /// <summary>
    ///  登录
    /// </summary>
    /// <param name="loginRequets"></param>
    /// <returns></returns>
    /// <exception cref="ValidatorException">校验异常</exception>
    /// <exception cref="BusinessException">运行异常</exception>
    public async Task<string> Login(LoginRequets loginRequets)
    {
        var validaionResult = _loginValidator.Validate(loginRequets);
      
        if (!validaionResult.IsValid)
        {
            throw new ValidatorException(validaionResult.Errors);
        }
        //SingleOrDefault 获取满足条件的单个元素，如果序列中没有或者有多个满足条件的元素，就返回默认值或者抛出异常
        //SingleAsync 的返回结果是 Task<T>，可以使用var来接收。
            // 如果查询结果为空 抛出 IvalidoperationException 异常
            // 如果查询结果大于一个元素，就抛出InvalidOperationException
            // 可以进行异步查询
        //与SingleOrDefaultAsync的区别：SingleOrDefaultAsync类似于SingleAsync，但它在查询结果为空时不会抛出异常，而是返回default(T)。
        var user =await _userRepository.GetByName(loginRequets.Name);
        
        if (user.Count>1)
            throw new BusinessException("账号不唯一");
        if (loginRequets.Password != user[0].Password)
            throw new BusinessException("密码出错");
        if (user[0].Status==0)
            throw new BusinessException("账号被禁用");
        var data = JwtHelper.CreateToken(loginRequets.Name,loginRequets.Password,user[0].Id);
        return data.Token;

    }
    
    /// <summary>
    /// 分页查询
    /// </summary>
    /// <param name="keyWord">关键字</param>
    /// <param name="pageIndex">页码</param>
    /// <param name="pageSize">页面大小</param>
    /// <returns></returns>
    public async Task<IQueryable<UserResponse>> GetUsersByPage(string keyWord,int pageIndex,int pageSize)
    {
        return await _userRepository.GetAllByPage( keyWord, pageIndex, pageSize);

    }

    /**
     * 注册 
     */
    public async Task<bool> Register(RegisterRequest registerRequest)
    { 
        var validaionResult = _registerValidator.Validate(registerRequest);
        if (!validaionResult.IsValid)
            throw new ValidatorException(validaionResult.Errors);
        var user =
            await _userRepository.GetByNameOrPhone(registerRequest.Name,registerRequest.Phone);
        if (user != null)
        {
            throw new BusinessException("用户名称或者手机号码已存在");
        }
        // 对象映射
        var res= await _userRepository.Add(_mapper.Map<User>(registerRequest));
        return res;
    }

    /**
     * 根据Name获取用户信息
     */
    public async Task<UserResponse> getUserByName(string name)
    {
        var user= await _userRepository.GetByName(name);
        if (user.Count>1)
            throw new BusinessException("账号不唯一");
        if (user[0].Status==0)
            throw new BusinessException("账号被禁用");
        return _mapper.Map<UserResponse>(user[0]);
    }
}